/**
 ** Copyright (c) 2010, GE Healthcare
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 ** 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **    following disclaimer.
 ** 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 **    disclaimer in the documentation and/or other materials provided with the distribution.
 ** 3. Neither the name of the GE Healthcare nor the names of its contributors may be used to endorse or promote products
 **    derived from this software without specific prior written permission.
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * This software was created by its contributors for NHINDirect.org for the sole purpose of demonstrating the
 * viability of using Integrating the Healthcare Enterprise (IHE) in accordance with the proposed
 * IHE NHIN Direct Specfication.
 *
 * References:
 * http://nhindirect.org/
 * http://nhindirect.org/NHIN+Direct+Abstract+Model
 * http://nhindirect.org/IHE+NHIN+Direct+Specification
 *
 * Contributors:
 * mailto:/matt.potter@ge.com
 */

package org.nhindirect;

import org.apache.log4j.Logger;
import org.apache.mailet.Mail;
import org.apache.mailet.base.GenericMailet;
import org.openhealthtools.ihe.xds.source.SubmitTransactionData;

import javax.mail.Message;
import javax.mail.MessagingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;

/**
 * An Apache James Mailet that converts clinical messages into IHE Cross-Enterprise Document Reliability (XDR)
 * messages and transmits them to an XDR Document Recipient via IHE XDS.b Provide and Register transaction (ITI-41).
 */
public class XDRMailet extends GenericMailet {

    private static final Logger LOGGER = Logger.getLogger(XDRMailet.class);

    /**
     * Relax the OHT IHE Profiles CDA validation to allow meta-data extraction to work correctly on
     * CDA instances that carry CCD or HITSP C83 extensions
     */
    static {
        System.setProperty("relax.validation", "true");
    }

    static final String DEFAULT_XDR_SOURCE_ID = "1.3.6.1.4.1.21367.2010.1.2.300";
    static final String DEFAULT_XDR_SOURCE_AGENT_NAME = "nhind-smtp";
    static final String DEFAULT_XDR_DOCUMENT_RECIPIENT_ENDPOINT = "nhind-smtp";

    private URI xdrEndpointUri;
    private String xdrSourceId;
    private String xdrSourceAgentName;

    @Override
    public void service(Mail mail) throws MessagingException {

        try {
            SubmitTransactionData txnData = XDSMimeMessageTransformer.convert(mail.getMessage());
            XDRDocumentSource xdrDocumentSource = new XDRDocumentSource(xdrSourceId, xdrSourceAgentName, xdrEndpointUri);
            try {
                LOGGER.info(MessageFormat.format("XDRMailet sending mail from {0} containing {1} document(s) to intendedRecipient {2} at XDR endpoint {3}",
                        mail.getMessage().getFrom()[0].toString(),
                        txnData.getMetadata().getDocumentEntry().size(),
                        mail.getMessage().getRecipients(Message.RecipientType.TO)[0].toString(),
                        xdrEndpointUri.toASCIIString()));
            } catch (Exception e) {
                LOGGER.info("XDRMailet message logging error!", e);
            }
            xdrDocumentSource.submit(txnData);
            mail.setState(Mail.GHOST);
        } catch (Throwable e) {
            e.printStackTrace();
            LOGGER.error("XDRMailet deliver failure", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void init() throws MessagingException {

        xdrSourceId = getInitParameter("sourceOid", DEFAULT_XDR_SOURCE_ID);
        xdrSourceAgentName = getInitParameter("sourceAgentName", DEFAULT_XDR_SOURCE_AGENT_NAME);

        try {
            xdrEndpointUri = new URI(this.getInitParameter("uri", DEFAULT_XDR_DOCUMENT_RECIPIENT_ENDPOINT));
        } catch (URISyntaxException e) {
            throw new MessagingException(e.getMessage());
        }

        LOGGER.info(MessageFormat.format("XDRMailet [sourceAgentName={0} sourceId={1} uri={2}] initialized",
                xdrSourceAgentName, xdrSourceId, xdrEndpointUri.toASCIIString()));
    }

}
